package store

import (
	"sort"

	"file_explorer/common/consts"
	"file_explorer/model"
	"file_explorer/service/eventbus"
	"file_explorer/service/task"
	"file_explorer/view/packed_widgets"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/theme"
)

type RenameTabContext struct {
	DefaultTabContext

	FileInfos    []*model.ModifiedFileInfo
	CheckedFiles []*model.ModifiedFileInfo

	Rules        []model.RenameRule
	CheckedRules []model.RenameRule
}

func (ctx *RenameTabContext) GetTabType() string {
	return consts.TabTypeRename
}

func (ctx *RenameTabContext) GetTabLabel() string {
	return "批量重命名"
}

func (ctx *RenameTabContext) GetTabIcon() fyne.Resource {
	return theme.MenuIcon()
}

func (ctx *RenameTabContext) SortFileInfos(cmp func(a, b *model.ModifiedFileInfo) bool) {
	sort.Slice(ctx.FileInfos, func(i, j int) bool {
		return cmp(ctx.FileInfos[i], ctx.FileInfos[j])
	})
}

func (ctx *RenameTabContext) reset() {
	for _, fileInfo := range ctx.FileInfos {
		fileInfo.New.Name = fileInfo.Old.Name
	}
}

func (ctx *RenameTabContext) ExecuteRules() {
	if len(ctx.FileInfos) == 0 || len(ctx.Rules) == 0 {
		return
	}

	ctx.reset()

	for _, rule := range ctx.Rules {
		rule.BatchExecute(ctx.FileInfos)
	}

	ctx.ProduceEvent(eventbus.EventKeyRenameTabCtxResChange, nil)
}

func (ctx *RenameTabContext) Submit() {
	renameTask := task.NewBatchRenamer(ctx.FileInfos)
	ctx.GetGlobalContext().TaskManager.SubmitGlobalTask(renameTask)
	renameTask.SetOnFinish(func(costTime int64, ok bool, err error) {
		if ok && err == nil {
			packed_widgets.NotifyInfo("任务完成: %s", renameTask.GetLabel())
		} else if err != nil {
			packed_widgets.NotifyError("任务失败: %s，错误：%s", renameTask.GetLabel(), err.Error())
		}

		ctx.GetGlobalContext().TaskManager.DeleteGlobalTask(renameTask)

		for _, dir := range model.BatchGetDirs(ctx.FileInfos) {
			ctx.GetGlobalContext().RefreshTabIfExists(dir)
		}
	})
}

func NewRenameTabContext(opListCtx *OpListContext) *RenameTabContext {
	ctx := &RenameTabContext{
		DefaultTabContext: newDefaultTabContext(opListCtx.GetGlobalContext()),
		FileInfos:         model.BuildModifiedFileInfos(opListCtx.CheckedList),
	}

	return ctx
}
